package cn.outsourcing.supermarket.common.utils;

import cn.outsourcing.supermarket.common.CommonPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;

import java.lang.reflect.Field;

/**
 * 分页工具
 *
 * @author gzkemays
 * @since 2021/10/18 13:45
 */
@EqualsAndHashCode(callSuper = true)
@Data
@NoArgsConstructor
public class IPageUtils<T> extends Page<T> {
  private long page;
  private long limit;

  private interface Init<T> {
    /**
     * 配置分页信息
     *
     * @param pages {@link CommonPage} 子类
     * @param <V> 泛型类型的数据
     * @return Page 分页对象
     */
    <V> IPageUtils<T> properties(V pages);

    /**
     * 自定义构建
     *
     * @param <V> 返回的泛型类型
     * @return Page 分页对象
     */
    IPageUtils<T> create();
  }

  private IPageUtils(IPageUtilsBuilder<T> properties) {
    super.setSize(properties.limit);
    super.setCurrent(properties.page);
  }

  public static <T> IPageUtilsBuilder<T> init() {
    return new IPageUtilsBuilder<T>();
  }

  public static class IPageUtilsBuilder<T> implements Init<T> {
    long page;
    long limit;

    public IPageUtilsBuilder<T> page(long page) {
      this.page = page;
      return this;
    }

    public IPageUtilsBuilder<T> limit(long limit) {
      this.limit = limit;
      return this;
    }

    @Override
    public <V> IPageUtils<T> properties(V pages) {
      try {
        Field pageField = pages.getClass().getField("page");
        Field limitField = pages.getClass().getField("limit");
        pageField.setAccessible(true);
        limitField.setAccessible(true);
        long limit = (long) limitField.get(pages);
        this.page = (long) pageField.get(pages);
        this.limit = limit == 0 ? 10L : limit;
      } catch (NoSuchFieldException | IllegalAccessException e) {
        e.printStackTrace();
      }
      return new IPageUtils<T>(this);
    }

    @Override
    public IPageUtils<T> create() {
      IPageUtils<T> pageUtils = new IPageUtils<>();
      if (this.limit == 0) {
        this.limit = 10L;
      }
      pageUtils.setSize(this.limit);
      pageUtils.setCurrent(this.page);
      return pageUtils;
    }
  }
}
